package vn.com.bookstore.network;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import vn.com.bookstore.Config;
import vn.com.bookstore.ObjectNetwork;
import vn.com.bookstore.database.smng.LinkMng;
import vn.com.bookstore.database.sobject.Link;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.util.Log;

public class NetworkAdapter extends ObjectNetwork {
	public static final String TAG = "NetworkAdapter";

	HttpParams htpp;
	HttpClient httpclient;
	HttpResponse response;

	private Context context;
	private Handler handler;
	private OnNetworkListener listener;

	boolean result = false;
	String json = "";

	public NetworkAdapter(Context context, Handler handler, OnNetworkListener listener) {
		initHttp();
		this.context = context;
		this.listener = listener;
		this.handler = handler;
	}

	public void initHttp() {
		htpp = new BasicHttpParams();

		HttpConnectionParams.setConnectionTimeout(htpp, CONN_TIMEOUT);
		HttpConnectionParams.setSoTimeout(htpp, SOCKET_TIMEOUT);

		httpclient = new DefaultHttpClient(htpp);
		response = null;
	}

	public String sendHttpGet(final int idMethod, String url, ArrayList<NameValuePair> param, boolean forceLoad) {
		result = false;
		json = "";

		String restFulUrl = url + "/" + makeGetParams(param);
		LinkMng mng = new LinkMng(context);

		if (forceLoad) {
			HttpGet httpget = new HttpGet(url + makeGetParams(param));
			try {
				response = httpclient.execute(httpget);
				json = inputStreamToString(response.getEntity().getContent());
				result = true;

				// insert/update to database
				ArrayList<Link> lstJson = mng.select(LinkMng.url, restFulUrl);
				Link link = new Link(-1, restFulUrl,json,System.currentTimeMillis()+"");
				if (lstJson != null && !lstJson.isEmpty()) {
					mng.edit(lstJson.get(0)._id, link.getValues()+"");
				} else {
					mng.insertNewTo(link.getValues());
				}

			} catch (ClientProtocolException e) {
				e.printStackTrace();
				json = e.getMessage();
			} catch (IOException e) {
				e.printStackTrace();
				json = e.getMessage();
			} catch (Exception e) {
				e.printStackTrace();
				json = e.getMessage();
			}
		} else {
			// load from database
			ArrayList<Link> lstJson = mng.select(LinkMng.url, restFulUrl);
			if (lstJson != null && !lstJson.isEmpty()) {
				for (Link item : lstJson) {
					if (item.json.length() > 0) {
						json = item.json;
						result = true;
						break;
					}
				}
			} else {
				return sendHttpGet(idMethod, url, param, true);
			}
		}
		try {
			handler.post(new Runnable() {

				@Override
				public void run() {
					if (listener != null)
						listener.onResponse(idMethod, result, json);
				}
			});
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
		return json;
	}

	public String sendHttpPost(final int idMethod, String url, ArrayList<NameValuePair> param, boolean forceLoad) {
		result = false;
		json = "";

		String restFulUrl = url + "/" + makeGetParams(param);
		LinkMng mng = new LinkMng(context);
		
		if (forceLoad) {
			HttpPost httppost = new HttpPost(url);
			try {
				httppost.setEntity(new UrlEncodedFormEntity(param));
				response = httpclient.execute(httppost);
				json = inputStreamToString(response.getEntity().getContent());
				result = true;

				// insert/update to database
				ArrayList<Link> lstJson = mng.select(LinkMng.url, restFulUrl);
				Link link = new Link(-1, restFulUrl,json,System.currentTimeMillis()+"");
				if (lstJson != null && !lstJson.isEmpty()) {
					mng.edit(lstJson.get(0)._id, link.getValues()+"");
				} else {
					mng.insertNewTo(link.getValues());
				}

			} catch (ClientProtocolException e) {
				e.printStackTrace();
				json = e.getMessage();
			} catch (IOException e) {
				e.printStackTrace();
				json = e.getMessage();
			} catch (Exception e) {
				e.printStackTrace();
				json = e.getMessage();
			}
		} else {
			return sendHttpPost(idMethod, url, param, true);
//			// load from database
//			ArrayList<Link> lstJson = mng.select(LinkMng.url, restFulUrl);
//			if (lstJson != null && !lstJson.isEmpty()) {
//				for (Link item : lstJson) {
//					if (item.json.length() > 0) {
//						json = item.json;
//						result = true;
//						break;
//					}
//				}
//			} else {
//				return sendHttpPost(idMethod, url, param, true);
//			}
		}
		
		handler.post(new Runnable() {

			@Override
			public void run() {
				listener.onResponse(idMethod, result, json);
			}
		});
		return json;
	}

	public String sendHttpPut(int idMethod, String url, ArrayList<NameValuePair> param) {
		// String json = "";
		throw new UnsupportedOperationException();
		// return json;
	}

	public String sendHttpDelete(int idMethod, String url, ArrayList<NameValuePair> param) {
		// String json = "";
		throw new UnsupportedOperationException();
		// return json;
	}

	public interface OnNetworkListener {
		public void onResponse(int idMethod, boolean isSuccess, String json);
	}

	public void downloadImageHttpGet(final int idMethod, Context context, String imageName) {
		result = false;
		json = imageName;
		
		LinkMng mng = new LinkMng(context);
		ArrayList<Link> lstLink = mng.select(LinkMng.url, imageName);
		if(lstLink != null && !lstLink.isEmpty()){
			Link item = lstLink.get(0);
			result = true;
			json = item.json;
		}else{
			DefaultHttpClient client = getHttpClient();
			HttpGet get = null;
			String url = Config.getUrlImage(imageName); // build url of image
			get = new HttpGet(url);
			HttpResponse response = null;
			Log.d("Url : ", imageName);
			File file = null;
			try {
				response = client.execute(get);
				HttpEntity entity = response.getEntity();
				InputStream in = entity.getContent();
				file = new File(Config.getImageCacheFolderName(context) + imageName.hashCode()); // get
																						// external
																						// directory
				FileOutputStream out = new FileOutputStream(file);
				byte buf[] = new byte[BUFFER_SIZE];
				int len;

				while ((len = in.read(buf)) > 0) {
					out.write(buf, 0, len);
				}
				out.close();
				result = true;
				json = file.getAbsolutePath();
				Link link = new Link(-1, imageName, json, System.currentTimeMillis()+"");
				mng.insertNewTo(link.getValues());
			} catch (HttpHostConnectException e) {
				e.printStackTrace();
				if (file!=null && file.exists()) {
					file.delete();
				}
			} catch (ConnectTimeoutException e) {
				e.printStackTrace();
				if (file!=null && file.exists()) {
					file.delete();
				}
			} catch (SocketTimeoutException e) {
				e.printStackTrace();
				if (file!=null && file.exists()) {
					file.delete();
				}
			} catch (Exception e) {
				e.printStackTrace();
				if (file!=null && file.exists()) {
					file.delete();
				}
			} finally {
				client.getConnectionManager().shutdown();
			}
		}
		
		handler.post(new Runnable() {

			@Override
			public void run() {
				listener.onResponse(idMethod, result, json);
			}
		});
	}

	public static Bitmap getBitmapFromURL(String src) {
		try {
			URL url = new URL(src);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setUseCaches(true);
			InputStream input = connection.getInputStream();
			Bitmap myBitmap = BitmapFactory.decodeStream(input);
			return myBitmap;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
}
